namespace SimpleWebServices.Models
{
    using System.Collections.ObjectModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Web;
    using System.Xml.Serialization;
    using SimpleWebServices.Data;
    using SimpleWebServices.Web;
    using SimpleWebServices.Web.UI.Html;

    [XmlRoot("tenant")]
    public class Tenant : Record
    {
        public Tenant()
        {
            this.Favicons = new Collection<Favicon>();
            this.Elements = new ElementCollection();
            this.MasterPages = new DataCollection();
            this.StyleSheets = new Collection<StyleSheet>();
        }

        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "It's really not that confusing.")]
        public static Tenant Current
        {
            get
            {
                return Tenant.GetCurrent<Tenant>();
            }
        }

        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Can't deserialize if the setter is private.")]
        [XmlElement("elements")]
        public ElementCollection Elements
        {
            get;
            set;
        }

        [XmlIgnore]
        public override string Entity
        {
            get
            {
                Entity value = new Entity();
                value.Append(this.Elements);
                value.Append(this.Favicons);
                value.Append(this.MasterPages);
                value.Append(this.Name);
                value.Append(this.StyleSheets);

                return value;
            }
        }

        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Can't deserialize if the setter is private.")]
        [XmlArray("favicons")]
        [XmlArrayItem("favicon")]
        public Collection<Favicon> Favicons
        {
            get;
            set;
        }

        [XmlElement("master-pages")]
        public DataCollection MasterPages
        {
            get;
            set;
        }

        [XmlAttribute("name")]
        public string Name
        {
            get;
            set;
        }

        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Can't deserialize if the setter is private.")]
        [XmlArray("stylesheets")]
        [XmlArrayItem("stylesheet")]
        public Collection<StyleSheet> StyleSheets
        {
            get;
            set;
        }

        public static T GetCurrent<T>()
            where T : Tenant
        {
            T value = default(T);

            AbsoluteUri urn = HttpContextFactory.Current.Request.TenantUrn();
            if (null != urn)
            {
                value = Record.Retrieve<T>(urn);
            }

            return value;
        }

        public static string Format(string value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                Tenant tenant = Tenant.Current;
                if (null != tenant)
                {
                    value = value
                        .Replace("{tenant-name}", tenant.Name)
                        .Replace("{tenant-path}", HttpContextFactory.Current.Request.TenantPath());
                }
            }

            return value;
        }

        public static string HtmlAttributeEncode(string value)
        {
            return HttpUtility.HtmlAttributeEncode(Tenant.Format(value));
        }

        public static string HtmlEncode(string value)
        {
            string result = value;
            if (!string.IsNullOrEmpty(result))
            {
                result = HttpUtility.HtmlEncode(Tenant.Format(value)).Replace("'", "&apos;");
            }

            return result;
        }

        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "This method wraps HttpUtility.UrlPathEncode(string).")]
        public static string UrlPathEncode(string value)
        {
            return HttpUtility.UrlPathEncode(Tenant.Format(value));
        }
    }
}